﻿//-----------------------------------------------------------------------
// <copyright file="Program.cs" company="DylanBox">
// Copyright (c) DylanBox Corporation. All rights reserved.
// </copyright>
// <summary></summary>
// <reference>
//  1．Adapter模式主要应用于“希望复用一些现存的类，但是接口又与复用环境要求不一致的情况”，在遗留代码复用、类库迁移等方面非常有用。
//  2．Adapter模式有对象适配器和类适配器两种形式的实现结构，但是类适配器采用“多继承”的实现方式，带来了不良的高耦合，所以一般不推荐使用。对象适配器采用“对象组合”的方式，更符合松耦合精神。

//      no need change, we can use the old existed interface
//      Adapters are used to enable objects with different interfaces to communicate with each other.
//    
//  •Target 
//      ◦defines the domain-specific interface that Client uses. 
//  •Adapter 
//      ◦adapts the interface Adaptee to the Target interface.
//  •Adaptee  
//      ◦defines an existing interface that needs adapting.
//  •Client 
//      ◦collaborates with objects conforming to the Target interface. 
// </reference>
// <author>Dylan</author>
//-----------------------------------------------------------------------
using System;

namespace Structural
{
    /// <summary>
    /// MainApp startup class for Structural
    /// Adapter Design Pattern.
    /// 
    /// Scenario 1: 
    /// old library's api, B.api()   
    /// now, our library, A, want to use this api(),   
    /// 在中间加一个adapter，叫c, 这样A调用c，c调用B； 
    /// 
    /// Scenario 2:
    /// A 调用了 B 的方法b, 但是b方法的参数改了 ， 这样A的代码也得改；
    /// 在中间加一个adapter，叫c, 这样A调用c，c调用B；
    /// 当B的b方法发生参数改变时，不用改A，改c就可以了。 这样可以保证变化性集中到c里面。  
    /// </summary>
    class MainApp
    {
        /// <summary>
        /// Entry point into console application.
        /// </summary>
        static void Main()
        {
            // no adapter
            Target tar = new Target();
            tar.Request();  // if Request() change, we must change the client code!

            // so we use Adapter pattern, change will be isolated in Adapter class
            // Create adapter and place a request
            Target target = new Adapter();
            target.Request();

            // Wait for user
            Console.ReadKey();
        }
    }
    
    /// <summary>
    /// The 'Target' class,
    /// domain-specific interface that Client uses.
    /// </summary>
    class Target
    {
        public virtual void Request()
        {
            Console.WriteLine("Called Target Request()");
        }
    }
}
